<template>
  <div class="image-uploader">
    <!-- 预览区域 -->
    <div class="preview-area" @click="showUploadOptions">
      <!-- 默认状态显示上传图标 -->
      <div class="upload-placeholder" v-if="!displayImage">
        <i class="iconfont icon-upload"></i>
        <span class="upload-text">点击上传图片</span>
      </div>
      
      <!-- 有图片时显示预览 -->
      <img v-if="displayImage" :src="displayImage" class="preview-image" />
      
      <!-- 底部操作栏 -->
      <div class="preview-actions" v-if="displayImage && !isUploading">
        <button class="v-button danger small" @click.stop="removeImage">
          <i class="iconfont icon-delete"></i> 删除
        </button>
      </div>
      
      <!-- 上传进度 -->
      <div class="upload-progress" v-if="isUploading">
        <div class="progress-bar" :style="{ width: uploadProgress + '%' }"></div>
        <span class="progress-text">{{ uploadProgress }}%</span>
      </div>
    </div>
    
    <!-- 隐藏的文件输入 -->
    <input
      type="file"
      ref="fileInput"
      @change="handleFileSelect"
      :accept="accept"
      style="display: none"
    />
    
    <!-- 上传选项弹窗 -->
    <vPopup v-model="showUploadOptionsDialog" title="选择图片" width="800px" @confirm="confirmImageSelection">
      <div class="upload-options">
        <div class="option-tabs">
          <button
            class="tab-button"
            :class="{ active: activeTab === 'upload' }"
            @click="activeTab = 'upload'"
          >
            上传新图片
          </button>
          <button
            class="tab-button"
            :class="{ active: activeTab === 'select' }"
            @click="activeTab = 'select'"
          >
            从已上传中选择
          </button>
        </div>
        
        <div class="tab-content">
          <!-- 上传新图片 -->
          <div v-if="activeTab === 'upload'" class="upload-tab">
            <div class="upload-area" @click="triggerFileInput">
              <i class="iconfont icon-upload"></i>
              <p>点击或拖拽文件到此处上传</p>
              <input
                type="file"
                ref="fileInput"
                @change="handleFileSelect"
                :accept="accept"
                style="display: none"
              />
            </div>
            <div class="upload-hint">
              支持 {{ accept }} 格式，大小不超过 {{ maxSize }}MB
            </div>
          </div>
          
          <!-- 从已上传中选择 -->
          <div v-if="activeTab === 'select'" class="select-tab">
            <div class="image-list">
              <div
                v-for="image in uploadedImages"
                :key="image.id"
                class="image-item"
                @click="previewSelectedImage(image.url)"
              >
                <img :src="image.url" :alt="image.file_name" />
                <div class="image-meta">
                  <span>{{ image.file_name }}</span>
                  <span>{{ formatFileSize(image.file_size) }}</span>
                </div>
                <div class="checkbox-wrapper-4" @click.stop>
                  <input
                    class="inp-cbx"
                    :id="'image-' + image.id"
                    type="checkbox"
                    :checked="selectedImage === image.url"
                   @change.stop="selectImage(image.url)"
                  />
                  <label class="cbx" :for="'image-' + image.id">
                    <span>
                      <svg width="12px" height="10px">
                        <use xlink:href="#check-4"></use>
                      </svg>
                    </span>
                  </label>
                </div>
              </div>
            </div>
            
            <div class="pagination" v-if="pagination.totalPages > 1">
              <button
                class="v-button"
                :disabled="pagination.page === 1"
                @click="loadImages(pagination.page - 1)"
              >
                上一页
              </button>
              <span class="page-info">
                第 {{ pagination.page }} 页 / 共 {{ pagination.totalPages }} 页
              </span>
              <button
                class="v-button"
                :disabled="pagination.page === pagination.totalPages"
                @click="loadImages(pagination.page + 1)"
              >
                下一页
              </button>
            </div>
          </div>
        </div>
      </div>
      
      <template #footer>
        <button class="v-button outline" @click="showUploadOptionsDialog = false">
          取消
        </button>
        <button
          class="v-button primary"
          @click="confirmImageSelection"
          :disabled="!selectedImage"
        >
          确定
        </button>
      </template>
      
      <!-- SVG符号定义 -->
      <svg class="inline-svg" style="display: none;">
        <symbol id="check-4" viewBox="0 0 12 10">
          <polyline points="1.5 6 4.5 9 10.5 1"></polyline>
        </symbol>
      </svg>
    </vPopup>
    
    <!-- 图片预览弹窗 -->
    <vPopup
      v-model="showImagePreviewDialog"
      title="图片预览"
      width="auto"
      :showFooter="false"
    >
      <img :src="previewImageUrl" class="preview-large-image" />
    </vPopup>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted } from "vue";
import { get, upload } from "@/utils/request";
import { vToast } from "@/plugins/vToast";

const props = defineProps({
  modelValue: String,  // 接收外部v-model
  maxSize: {
    type: Number,
    default: 5
  },
  accept: {
    type: String,
    default: "image/*"
  }
});

const emit = defineEmits(['update:modelValue', 'upload-success']);

const fileInput = ref(null);
const isUploading = ref(false);
const uploadProgress = ref(0);
const localImage = ref(null); // 本地选择的图片（未上传）
const showUploadOptionsDialog = ref(false);
const activeTab = ref('upload');
const uploadedImages = ref([]);
const selectedImage = ref(null);
const showImagePreviewDialog = ref(false);
const previewImageUrl = ref('');
const pagination = ref({
  page: 1,
  pageSize: 15,
  total: 0,
  totalPages: 1
});

// 计算显示的图片（优先显示本地选择的，其次显示外部传入的）
const displayImage = computed(() => {
  return localImage.value || props.modelValue;
});

// 验证文件类型的辅助函数
const isValidFileType = (fileType, acceptTypes) => {
  // 如果acceptTypes是'image/*'，直接检查文件类型是否以'image/'开头
  if (acceptTypes === 'image/*') {
    return fileType.startsWith('image/');
  }
  
  // 处理多个文件类型的情况，如'image/jpeg,image/png'
  const validTypes = acceptTypes.split(',').map(type => type.trim());
  
  // 检查是否有完全匹配的类型
  if (validTypes.includes(fileType)) {
    return true;
  }
  
  // 检查是否有通配符类型匹配
  for (const type of validTypes) {
    if (type.endsWith('*')) {
      const baseType = type.slice(0, -1); // 移除通配符
      if (fileType.startsWith(baseType)) {
        return true;
      }
    }
  }
  
  return false;
};

// 监听外部modelValue变化
watch(() => props.modelValue, (newVal) => {
  // 如果外部清空了值，同时清空本地图片
  if (!newVal) {
    localImage.value = null;
  }
});

// 显示上传选项弹窗
const showUploadOptions = () => {
  showUploadOptionsDialog.value = true;
  activeTab.value = 'upload';
  selectedImage.value = null;
};

// 触发文件选择
const triggerFileInput = () => {
  fileInput.value.click();
};

// 处理文件选择
const handleFileSelect = async (e) => {
  const file = e.target.files[0];
  if (!file) return;

  // 验证文件类型
  if (!isValidFileType(file.type, props.accept)) {
    vToast.warning(`请选择${props.accept}类型的文件`);
    return;
  }

  // 验证文件大小
  if (file.size > props.maxSize * 1024 * 1024) {
    vToast.warning(`文件大小不能超过${props.maxSize}MB`);
    return;
  }

  // 创建预览
  const reader = new FileReader();
  reader.onload = (e) => {
    localImage.value = e.target.result; // 存储本地图片
    startUpload(file); // 自动上传
    showUploadOptionsDialog.value = false;
  };
  reader.readAsDataURL(file);
};

// 开始上传
const startUpload = async (file) => {
  isUploading.value = true;
  uploadProgress.value = 0;

  try {
    const formData = new FormData();
    formData.append('file', file);

    const res = await upload('/upload/upload', formData, {
      headers: {
        'Content-Type': 'multipart/form-data'
      },
      onUploadProgress: (progressEvent) => {
        if (progressEvent.lengthComputable) {
          uploadProgress.value = Math.round(
            (progressEvent.loaded / progressEvent.total) * 100
          );
        }
      }
    });

    if (res.code===200) {
      vToast.success('上传成功');
      emit('update:modelValue', res.data.url); // 更新v-model
      emit('upload-success', res.data);
      localImage.value = null; // 清空本地图片，改用外部传入的URL
    } else {
      vToast.error(res.message || '上传失败');
      removeImage();
    }
  } catch (error) {
    vToast.error('上传过程中出错');
    console.error(error);
    removeImage();
  } finally {
    isUploading.value = false;
  }
};

// 删除图片
const removeImage = () => {
  localImage.value = null;
  fileInput.value.value = "";
  emit('update:modelValue', null); // 通知外部清空
};

// 加载已上传图片列表
const loadImages = async (page = 1) => {
  try {
    const res = await get('/upload/list', {
      page,
      pageSize: pagination.value.pageSize
    });
    
    if (res.code === 200) {
      uploadedImages.value = res.data.list || [];
      pagination.value = {
        page: res.data.pagination.page || 1,
        pageSize: res.data.pagination.pageSize || 15,
        total: res.data.pagination.total || 0,
        totalPages: res.data.pagination.totalPages || 1
      };
    } else {
      vToast.error(res.msg || '获取图片列表失败');
    }
  } catch (error) {
    vToast.error('获取图片列表失败');
    console.error(error);
  }
};

// 选择图片
const selectImage = (url) => {
  selectedImage.value = selectedImage.value === url ? null : url;
};

// 预览选中的图片
const previewSelectedImage = (url) => {
  previewImageUrl.value = url;
  showImagePreviewDialog.value = true;
};

// 确认图片选择
const confirmImageSelection = () => {
  console.log(  selectedImage.value)
  if (selectedImage.value) {
    emit('update:modelValue', selectedImage.value);
    showUploadOptionsDialog.value = false;
  }
};

// 格式化文件大小
const formatFileSize = (bytes) => {
  if (bytes < 1024) return bytes + ' B';
  if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
  return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
};

// 初始化时加载第一页图片
onMounted(() => {
  loadImages();
});
</script>

<style scoped lang="less">
.image-uploader {
  position: relative;
  display: inline-block;
}

.preview-area {
  position: relative;
  width: 140px;
  height: 140px;
  border: 1px dashed #ddd;
  border-radius: 4px;
  overflow: hidden;
  cursor: pointer;
  transition: all 0.3s;
  
  &:hover {
    border-color: var(--v-theme);
  }
  
  .upload-placeholder {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    color: #999;
    
    .iconfont {
      font-size: 32px;
      margin-bottom: 8px;
    }
    
    .upload-text {
      font-size: 12px;
    }
  }
  
  .preview-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
  
  .preview-actions {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    background: rgba(0, 0, 0, 0.7);
    padding: 6px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
}

.upload-progress {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 6px;
  background: #555;
  
  .progress-bar {
    height: 100%;
    background-color: var(--v-theme);
    transition: width 0.3s;
  }
  
  .progress-text {
    position: absolute;
    right: 4px;
    top: -18px;
    font-size: 10px;
    color: white;
  }
}

.v-button {
  &.small {
    padding: 4px 8px;
    font-size: 12px;
    min-width: auto;
    height: auto;
    
    &.danger {
      background-color: var(--v-danger);
      color: white;
      
      &:hover {
        background-color: var(--v-danger-dark);
      }
    }
  }
}

/* 上传选项弹窗样式 */
.upload-options {
  padding: 16px;
  
  .option-tabs {
    display: flex;
    border-bottom: 1px solid #eee;
    margin-bottom: 16px;
    
    .tab-button {
      padding: 8px 16px;
      background: none;
      border: none;
      border-bottom: 2px solid transparent;
      cursor: pointer;
      font-size: 14px;
      color: #666;
      
      &.active {
        color: var(--v-theme);
        border-bottom-color: var(--v-theme);
        font-weight: 500;
      }
      
      &:hover:not(.active) {
        color: var(--v-theme);
      }
    }
  }
  
  .tab-content {
    min-height: 300px;
    
    .upload-tab {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      height: 300px;
      
      .upload-area {
        width: 100%;
        height: 200px;
        border: 2px dashed #ddd;
        border-radius: 4px;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        cursor: pointer;
        transition: all 0.3s;
        
        &:hover {
          border-color: var(--v-theme);
          background-color: #f9f9f9;
        }
        
        .iconfont {
          font-size: 48px;
          color: #999;
          margin-bottom: 8px;
        }
        
        p {
          color: #666;
          margin: 0;
        }
      }
      
      .upload-hint {
        margin-top: 12px;
        font-size: 12px;
        color: #999;
      }
    }
    
    .select-tab {
      .image-list {
        display: grid;
        grid-template-columns: repeat(5, 1fr);
        gap: 12px;
        max-height: 400px;
        overflow-y: auto;
        padding: 8px;
        
        .image-item {
          position: relative;
          height: 120px;
          border: 1px solid #eee;
          border-radius: 4px;
          overflow: hidden;
          cursor: pointer;
          transition: all 0.3s;
          
          &:hover {
            border-color: var(--v-theme);
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
          }
          
          img {
            width: 100%;
            height: 80px;
            object-fit: cover;
          }
          
          .image-meta {
            padding: 4px;
            font-size: 12px;
            display: flex;
            flex-direction: column;
            
            span {
              white-space: nowrap;
              overflow: hidden;
              text-overflow: ellipsis;
            }
          }
          
          .checkbox-wrapper-4 {
            position: absolute;
            top: 4px;
            right: 4px;
            z-index: 2;
          }
        }
      }
      
      .pagination {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 16px;
        margin-top: 16px;
        padding-top: 16px;
        border-top: 1px solid #eee;
        
        .page-info {
          font-size: 14px;
          color: #666;
        }
      }
    }
  }
}

/* 图片预览样式 */
.preview-large-image {
  max-width: 80vw;
  max-height: 80vh;
  object-fit: contain;
}

/* 复选框样式 */
.checkbox-wrapper-4 * {
  box-sizing: border-box;
}
.checkbox-wrapper-4 .cbx {
  -webkit-user-select: none;
  user-select: none;
  cursor: pointer;
  overflow: hidden;
  transition: all 0.2s ease;
  display: inline-block;
  position: relative;
  width: 20px;
  height: 20px;
}
.checkbox-wrapper-4 .cbx span {
  float: left;
  vertical-align: middle;
  transform: translate3d(0, 0, 0);
}
.checkbox-wrapper-4 .cbx span:first-child {
  position: relative;
  width: 18px;
  height: 18px;
  border-radius: 4px;
  transform: scale(1);
  border: 1px solid #cccfdb;
  transition: all 0.2s ease;
  box-shadow: 0 1px 1px rgba(0,16,75,0.05);
  background: white;
}
.checkbox-wrapper-4 .cbx span:first-child svg {
  position: absolute;
  top: 3px;
  left: 2px;
  fill: none;
  stroke: #fff;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 16px;
  stroke-dashoffset: 16px;
  transition: all 0.3s ease;
  transition-delay: 0.1s;
  transform: translate3d(0, 0, 0);
}
.checkbox-wrapper-4 .inp-cbx {
  position: absolute;
  visibility: hidden;
}
.checkbox-wrapper-4 .inp-cbx:checked + .cbx span:first-child {
  background: var(--v-theme);
  border-color: var(--v-theme);
  animation: wave-4 0.4s ease;
}
.checkbox-wrapper-4 .inp-cbx:checked + .cbx span:first-child svg {
  stroke-dashoffset: 0;
}
.checkbox-wrapper-4 .inline-svg {
  position: absolute;
  width: 0;
  height: 0;
  pointer-events: none;
  user-select: none;
}
@keyframes wave-4 {
  50% {
    transform: scale(0.9);
  }
}
</style>